import logging
from logging import handlers
import os
from collections import defaultdict
from config import base_url, log


def default_level():
    return logging.INFO


# 日志等级映射，不存在的key取值为info
log_level = defaultdict(default_level)
log_level["debug"] = logging.DEBUG
log_level["info"] = logging.INFO
log_level["warning"] = logging.WARNING
log_level["error"] = logging.ERROR


# 单例装饰器，限单线程使用。多线程使用需去掉并更改使用方式
class Singleton(object):
    __instance = None

    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = super(Singleton, cls).__new__(cls)
        return cls.__instance


# 日志设置
class Logger(Singleton):

    def __init__(self, filename="project.log", write_level="debug",
                 console_level="debug", when="D", back_count=10):
        super(Logger, self).__init__()
        filename = self.new_file(filename)
        self.logger = logging.getLogger(filename)
        format_str = logging.Formatter(fmt="%(asctime)s %(filename)s %(levelname)s:%(message)s",
                                       datefmt="%Y-%m-%d %H:%M:%S")
        self.logger.setLevel(log_level[write_level.lower()])

        # 添加控制台输出
        sh = logging.StreamHandler()
        sh.setLevel(log_level[console_level.lower()])
        sh.setFormatter(format_str)

        # 设置文件分割模式
        """
        实例化TimedRotatingFileHandler
        interval是时间间隔，
        backupCount是备份文件的个数，如果超过这个数，就会自动删除，
        when是间隔的时间单位，单位有以下几种：
            S 秒
            M 分
            H 小时
            D 天
            W 每星期（interval==0时代表星期一）
            midnight 每天凌晨
        """
        th = handlers.TimedRotatingFileHandler(filename=filename, when=when,
                                               backupCount=back_count, encoding="utf-8")
        th.setFormatter(format_str)
        self.logger.addHandler(sh)
        self.logger.addHandler(th)

    @classmethod
    def new_file(cls, filename):
        folder = f"{base_url}/log"
        if not os.path.exists(folder):
            os.mkdir(folder)
        new_file = f"{folder}/{filename}"
        return new_file


logger = Logger(**log).logger

